﻿
//给定一个包含
//�
//n个点
//�
//m条边的有向无环图，求出该图的拓扑序。若图的拓扑序不唯一，输出任意合法的拓扑序即可。若该图不能拓扑排序，输出
//
//)，表示点的个数和边的条数。
//接下来的
//m行，每行输入两个整数
//    之间有一条有向边。
//    输出描述：
//    若图存在拓扑序，输出一行
//    �
//    n个整数，表示拓扑序。否则输出
//    −
//    1
//    −1。
//    示例1
//    输入：
//    5 4
//    1 2
//    2 3
//    3 4
//    4 5
//    复制
//    输出：
//    1 2 3 4 5


//思路：bfs利用队列依次取出入度为0的点，然后消除它所指向的点的入度，然后把它输出，依次重复，入度为0就放入队列;其次就是考虑环不成立问题

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int n, m;
const int N = 2e5 + 1;
vector<vector<int>> dir(N);//某个节点箭头指向信息。
vector<int>d(N);//入度记录
queue<int>q;
vector<int> ret;
void tupo_order() {
    //从头找到入度为0的第一个节点：
    for (int i = 1; i <= n; i++) {
        if (d[i] == 0) q.push(i);
    }
    while (q.size()) {
        int cur = q.front();
        q.pop();
        ret.emplace_back(cur);//存入返回结果中
        //找它它所指向的顶点，把它们的入度依次--，就可以把它拆出了。
        for (int j = 0; j < dir[cur].size(); j++) {
            if (--d[dir[cur][j]] == 0) q.push(dir[cur][j]);
        }
    }
}
int main() {
    cin >> n >> m;
    while (m--) {
        int x, y;
        cin >> x >> y;
        dir[x].push_back(y);//x->y，数组中存储x的箭头指向，方便x入度为0时放入队列后取到它的时候把它所指向的顶点入度--；
        d[y]++;
    }
    tupo_order();
    if (ret.size() != n) cout << -1 << endl;//如果最后size！=n，说明存在环（此时自己成环->入度！=0->无法放入队列->size!=n），不能拓扑排序

    else {
        for (int i = 0; i < n - 1; i++) {
            cout << ret[i] << " ";
        }
        cout << ret[n - 1];
    }

    return 0;
}
// 64 位输出请用 printf("%lld")